package cn.ilikes.tools.nosql.jpa.query.iquerys;

import cn.ilikes.tools.nosql.jpa.JPASQLPersistenUnitEnv;
import cn.ilikes.tools.nosql.jpa.SysConfigs;
import cn.ilikes.tools.nosql.jpa.clients.indexs.IClientIndex;
import cn.ilikes.tools.nosql.jpa.clients.indexs.units.LuceneQueryUtils;
import cn.ilikes.tools.nosql.jpa.clients.indexs.units.LuceneUtils;
import cn.ilikes.tools.nosql.jpa.metadatas.EntityMetaData;
import cn.ilikes.tools.nosql.jpa.metadatas.elements.EntityFields;
import cn.ilikes.tools.nosql.jpa.metadatas.elements.Relation;
import cn.ilikes.tools.nosql.jpa.query.JPASQLQueryRunTimeException;
import cn.ilikes.tools.nosql.jpa.query.pasers.ParentWhereList;
import cn.ilikes.tools.nosql.jpa.query.sql.element.Element;
import cn.ilikes.tools.nosql.jpa.query.sql.element.Properties;
import cn.ilikes.tools.nosql.jpa.query.sql.element.SQLTable;
import cn.ilikes.tools.nosql.jpa.query.sql.element.WhereList;
import cn.ilikes.tools.nosql.jpa.query.sql.element.Properties.Between;
import cn.ilikes.tools.nosql.jpa.query.sql.element.WhereList.ListType;
import cn.ilikes.tools.nosql.jpa.unitls.JPAUtils;

public class IndexQueryCreateFactory implements IIndexQueryCreateFactory {

	private JPASQLPersistenUnitEnv persistenUnitEnv;

	public IndexQueryCreateFactory(JPASQLPersistenUnitEnv persistenUnitEnv) {
		super();
		this.persistenUnitEnv = persistenUnitEnv;
	}

	public String createLunceQuerys(SQLTable kuTable, EntityMetaData entityMetaData) {
		StringBuffer result = new StringBuffer();
		Element whereList = kuTable.getWhereList();
		//result.append(" ( ");
		assignLunceVariable(whereList, entityMetaData, result, ListType.and);
		//result.append(" ) ");
		result.append(" AND +" + LuceneUtils.indexEntityCLassfield(entityMetaData));
		return result.toString();
	}

	/**
	 * 赋值
	 * 
	 * @param element
	 * @param parameters
	 */
	private void assignLunceVariable(Element element, EntityMetaData entityMetaData, StringBuffer result, ListType listType) {

		WhereList whereList = (WhereList) element;

		switch (whereList.getListType()) {
		case equals:
			paserEquals(whereList, entityMetaData, result, listType);
			break;
		case and:
			assignLunceVariable(whereList.getLeftList(), entityMetaData, result, ListType.and);
			result.append(" AND ");
			assignLunceVariable(whereList.getRightList(), entityMetaData, result, ListType.and);
			break;
		case or:
			result.append("(");
			assignLunceVariable(whereList.getLeftList(), entityMetaData, result, ListType.or);
			result.append(" OR ");
			assignLunceVariable(whereList.getRightList(), entityMetaData, result, ListType.or);
			result.append(")");
			break;
		case in:
			paserIn(whereList, entityMetaData, result);
			break;

		default:
			break;
		}
	}

	private void paserEquals(WhereList whereList, EntityMetaData entityMetaData, StringBuffer result, ListType listType) {
		Properties propertiesLeft = (Properties) whereList.getLeftList();
		Properties propertiesRight = (Properties) whereList.getRightList();
		String[] tok = ((String) propertiesLeft.getValue()).split(SysConfigs.jpa_entity_table_field);
		String tok_ = tok[1];
		EntityFields dntityFields = (entityMetaData.getEntityId().getFieldName().equals(tok_) ? entityMetaData.getEntityId() : entityMetaData.getEntityFields().get(tok_));
		if (!dntityFields.getIndexField().isAbleIndex())
			throw new JPASQLQueryRunTimeException("this  " + tok[1] + " fields  not indexed ");
		if (dntityFields == null)
			throw new JPASQLQueryRunTimeException("not find " + tok[1] + " fields ");
		if (dntityFields.getjPAField().getRelation().isAbleRelation()) {
			//throw new JPASQLQueryRunTimeException("fields "+tok_+"  have relation  in   entity :   "+dntityFields.getFieldName()+"   ");
			paserEqualsAbleRelation(whereList, dntityFields, tok, 1, result, entityMetaData);
		} else {
			result.append(" ( "
					+ (listType.equals(ListType.and) ? "+" : " ")
					+ LuceneQueryUtils.toLowerCase(LuceneQueryUtils.createLuceneFieldsName(entityMetaData.getEntityIndex().getIndexName(), dntityFields.getIndexField()
							.getName()))
					+ ":\""
					+ (((String) propertiesRight.getValue()).startsWith(":") ? (String) propertiesRight.getValue() : LuceneQueryUtils.toLowerCase(propertiesRight
							.getValue())) + "\" )");

		}

	}

	private void paserIn(WhereList whereList, EntityMetaData entityMetaData, StringBuffer result) {
		Properties propertiesLeft = (Properties) whereList.getLeftList();
		Properties propertiesRight = (Properties) whereList.getRightList();
		String[] tok = ((String) propertiesLeft.getValue()).split(SysConfigs.jpa_entity_table_field);
		String tok_ = tok[1];
		EntityFields dntityFields = (entityMetaData.getEntityId().getFieldName().equals(tok_) ? entityMetaData.getEntityId() : entityMetaData.getEntityFields().get(tok_));
		if (!dntityFields.getIndexField().isAbleIndex())
			throw new JPASQLQueryRunTimeException("this  " + tok[1] + " fields  not indexed ");
		if (dntityFields == null)
			throw new JPASQLQueryRunTimeException("not find " + tok[1] + " fields ");
		if (dntityFields.getjPAField().getRelation().isAbleRelation()) {
			//throw new JPASQLQueryRunTimeException("fields "+tok_+"  have relation  in   entity :   "+dntityFields.getFieldName()+"   ");
			paserEqualsAbleRelation(whereList, dntityFields, tok, 1, result, entityMetaData);
		} else {
			result.append(" (111+ "
					+ LuceneQueryUtils.toLowerCase(propertiesLeft.getValue())
					+ ":"
					+ (((String) propertiesRight.getValue()).startsWith(":") ? (String) propertiesRight.getValue() : LuceneQueryUtils.toLowerCase(propertiesRight
							.getValue())) + ")");

		}

	}

	private void paserEqualsAbleRelation(WhereList whereList, EntityFields dntityFields, String[] tok, int start, StringBuffer result, EntityMetaData entityMetaData) {

		JPASQLPersistenUnitEnv persistenUnitEnv = this.persistenUnitEnv;
		Relation relation = dntityFields.getjPAField().getRelation();
		Class<?> targetEntityClass = relation.getTargetEntity();
		//		EntityMetaData entityMetaData = persistenUnitEnv.getMetaDataManagerFactory().selectIEntityMetaData(targetEntityClass);
		//		start = start + 1;
		//		String fields = tok[start];
		//		EntityFields fieldsEdntityFields = (entityMetaData.getEntityId().getFieldName().equals(fields) ? entityMetaData.getEntityId() : entityMetaData.getEntityFields().get(fields));
		//		if (fieldsEdntityFields == null)	throw new JPASQLQueryRunTimeException("not find " + tok[1] + " fields ");
		if (dntityFields.getjPAField().getRelation().isAbleRelation()) {
			//paserEqualsAbleRelation(whereList,dntityFields, tok, start + 1, result);
			//} else {

			//result.append(" ( ");
			//result.append(IClientIndex.ENTITY_CLASS_FIELD + ":" + LuceneQueryUtils.toLowerCase(entityMetaData.getEntityClazz().getCanonicalName()));
			//result.append(" AND ");
			//String indexName = fieldsEdntityFields.getIndexField().getName();
			//String luceneFieldsName =  LuceneQueryUtils.toLowerCase(LuceneQueryUtils.createLuceneFieldsName(entityMetaData.getEntityIndex().getIndexName(), indexName));
			//Properties propertiesRight = (Properties) whereList.getRightList();
			//result.append(luceneFieldsName + ":"  +(((String)propertiesRight.getValue()).startsWith(":") ? (String)propertiesRight.getValue()  :  LuceneQueryUtils.toLowerCase(propertiesRight.getValue())));
			//result.append(" ) ");

			result.append(" ( ");

			String indexName = dntityFields.getIndexField().getName();
			String luceneFieldsName = LuceneQueryUtils.toLowerCase(LuceneQueryUtils.createLuceneFieldsName(entityMetaData.getEntityIndex().getIndexName(), indexName));
			Properties propertiesRight = (Properties) whereList.getRightList();
			result.append(luceneFieldsName
					+ ":"
					+ (((String) propertiesRight.getValue()).startsWith(":") ? (String) propertiesRight.getValue() : LuceneQueryUtils.toLowerCase(propertiesRight
							.getValue())));
			result.append(" ) ");

		}

	}

}
